package com.cxs.distributedencrypt.slice;

import com.cxs.distributedencrypt.RemoteAgentProxy;
import com.cxs.distributedencrypt.ResourceTable;
import com.cxs.distributedencrypt.ServiceAbility;
import com.cxs.distributedencrypt.util.DeviceUtils;
import com.cxs.distributedencrypt.util.PrefUtils;
import com.cxs.distributedencrypt.util.SecurityUtils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Text;
import ohos.agp.components.TextField;
import ohos.bundle.ElementName;
import ohos.data.preferences.Preferences;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.IRemoteObject;
import ohos.rpc.RemoteException;


public class MainAbilitySlice extends AbilitySlice {
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001000, "MainAbilitySlice");

    // 轻量级数据库
    private static Preferences preferences;
    private Button btnEncypt, btnDecrypt;
    private TextField tfPassword;
    private Text textInfo;
    private final static String KEY_CIPHER_TEXT = "KEY_CIPHER_TEXT";
    private RemoteAgentProxy remoteAgentProxy = null;
    private String ciphertext1, ciphertext2;
    private boolean isConnected = false;
    private final static int EVENT_CONNECTED_ID = 1001;
    private final static int EVENT_DISCONNECTED_ID = 1002;
    private final static long IS_ENCRYPT = 1003;
    private final static long IS_DECRYPT = 1004;
    private final static long DELAY_TIME = 1000;
    private static long timing = 0;
    private final static long TIME_OUT = 3;
    private long eventParam;


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);

        preferences = PrefUtils.getPreferences(getContext());
        initComponent();

        startService();
    }

    private void initComponent() {
        tfPassword = (TextField) findComponentById(ResourceTable.Id_tf_input_password);
        textInfo = (Text) findComponentById(ResourceTable.Id_text_info);
        // 加密
        btnEncypt = (Button) findComponentById(ResourceTable.Id_btn_encrypt);
        btnEncypt.setClickedListener(c -> {
            startService();
            if (isConnected) {
                // 已连接Service
                encrypt();
            } else {
                // 没有连接到Service
                eventParam = IS_ENCRYPT;
                eventHandler.sendEvent(EVENT_DISCONNECTED_ID);
            }
        });

        // 解密
        btnDecrypt = (Button) findComponentById(ResourceTable.Id_btn_decrypt);
        btnDecrypt.setClickedListener(c -> {
            startService();
            if (isConnected) {
                decrypt();
            } else {
                // 没有连接到Service
                eventParam = IS_DECRYPT;
                eventHandler.sendEvent(EVENT_DISCONNECTED_ID);
            }
        });
    }

    /**
     * 加密
     */
    private void encrypt() {
        if (remoteAgentProxy != null) {
            try {
                String password = tfPassword.getText();
                if (password.equals("")) { return; }
                String deviceId = DeviceUtils.getDeviceId();
                if (deviceId.equals("")) { return; }

                // 加密
                String ciphertext = SecurityUtils.encrypt(password);
                int startIndex = 0;
                int endIndex = ciphertext.length() / 2;
                ciphertext1 = ciphertext.substring(startIndex, endIndex);
                ciphertext2 = ciphertext.substring(endIndex);

                // 前半部分密文存入源设备的数据库
                preferences.putString(KEY_CIPHER_TEXT, ciphertext1);
                // 调用远程Service的setCiphertext方法存储下半部分密文
                remoteAgentProxy.setCiphertext(ciphertext2);
                getUITaskDispatcher().asyncDispatch(() -> {
                    textInfo.setText(ciphertext1);
                });
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 解密
     */
    private void decrypt() {
        if (remoteAgentProxy != null) {
            try {
                ciphertext2 = remoteAgentProxy.getCiphertext();
                String cleartext = SecurityUtils.decrypt(ciphertext1 + ciphertext2);
                getUITaskDispatcher().asyncDispatch(() -> {
                    textInfo.setText(cleartext);
                });
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    EventHandler eventHandler = new EventHandler(EventRunner.create()) {
        @Override
        protected void processEvent(InnerEvent event) {
            switch (event.eventId) {
                case EVENT_CONNECTED_ID:
                    isConnected = true;
                    System.out.println(event.param);
                    if (eventParam == IS_ENCRYPT) {
                        encrypt();
                    } else if (eventParam == IS_DECRYPT) {
                        decrypt();
                    }
                    break;
                case EVENT_DISCONNECTED_ID:
                    if (timing >= TIME_OUT) {
                        getUITaskDispatcher().asyncDispatch(() -> {
                            textInfo.append("\n超时");
                        });
                        break;
                    }
                    timing++;
                    getUITaskDispatcher().asyncDispatch(() -> {
                        textInfo.setText("等待连接中...");
                    });
                    if (!isConnected) {
                        eventHandler.sendEvent(EVENT_DISCONNECTED_ID, DELAY_TIME);
                    }
                    break;
            }
        }
    };

    /**
     * 连接远程Service
     */
    private void startService() {
        timing = 0;
        String deviceId = DeviceUtils.getDeviceId();
        if (deviceId.equals("")) { return; }
        if (remoteAgentProxy != null) { return; }

        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId(deviceId)
                .withBundleName(getBundleName())
                .withAbilityName(ServiceAbility.class.getName())
                .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                .build();
        intent.setOperation(operation);

        connectAbility(intent, new IAbilityConnection() {
            @Override
            public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
                remoteAgentProxy = new RemoteAgentProxy(iRemoteObject);
                isConnected = true;
                eventHandler.removeEvent(EVENT_DISCONNECTED_ID);
                eventHandler.sendEvent(EVENT_CONNECTED_ID);
            }

            @Override
            public void onAbilityDisconnectDone(ElementName elementName, int i) {
                remoteAgentProxy = null;
                isConnected = false;
            }
        });
    }

}
